﻿#include"stdafx.h"
#include"ServerDB.h"

int ServerDB::Table_Select(const char*tname,string db, vector<insert_model>fields, vector<struct_where>where, string&info) {
	cur_db=db.c_str();
	if (cur_db == "") {
		info = "Please choose a database !";
		return 0;
	}
	CString  tbPath; tbPath = L"data\\" + cur_db + L"\\" + cur_db + L".tb";

	//判断表名合法性
	if (!IsTable(tbPath, tname)) {
		info = "Incorrect table name !";
		return false;
	}
	
	CString DBPath; 
	CString Ctname; 
	Ctname = tname;
	DBPath = L"data\\" + cur_db + L"\\" + Ctname + L".tdf";
	file.Open(DBPath, CFile::modeRead | CFile::typeBinary, NULL);
	Table_Tdf tdf; 
	vector<Table_Tdf>vec_tdf;
	while (file.Read(&tdf, sizeof(tdf))) {
		vec_tdf.push_back(tdf);
	}
	file.Close();
	// 判断fields字段是否合法
	bool index = true;
	if (fields.size() == 1 && fields[0].key == "*") {
		fields.pop_back();
		for (unsigned int i = 0; i < vec_tdf.size(); i++) {
			insert_model m;
			m.key = vec_tdf[i].name;
			m.pos = vec_tdf[i].order;
			m.type = vec_tdf[i].type;
			m.mmSize = vec_tdf[i].param;
			fields.push_back(m);
		}
	}
	else {
		for (unsigned int i = 0; i < fields.size(); i++) {
			for (unsigned int j = 0; j < vec_tdf.size(); j++) {
				if (strcmp(vec_tdf[j].name, fields[i].key.c_str()) == 0) {
					fields[i].pos = vec_tdf[j].order;
					fields[i].mmSize = vec_tdf[j].param;
					fields[i].type = vec_tdf[j].type;
					index = false;
				}
			}
			if (index) {
				info = "Invalid column ";
				return 0;
			}
			index = true;
		}
	}


	//判断where字段是否合法
	index = true;
	for (unsigned int i = 0; i < where.size(); i++) {
		for (unsigned int j = 0; j < vec_tdf.size(); j++) {
			if (strcmp(vec_tdf[j].name, where[i].key.c_str()) == 0) {
				where[i].pos = vec_tdf[j].order;
				where[i].size = vec_tdf[j].param;
				where[i].index = vec_tdf[j].index;
				where[i].type = vec_tdf[j].type;
				if (where[i].type == "5" && !IsDateValid(where[i].value.c_str())) {
					info = "Invalid date in where";
					return 0;
				}
				index = false;
			}
		}
		if (index) {
			info = "Invalid column in where";
			return 0;
		}
		index = true;
	}

	Table_Tdf Ttdf = vec_tdf.back();
	int lenth = Ttdf.order + Ttdf.param;
	DBPath = L"data\\" + cur_db + L"\\" + Ctname + L".trd";
	file.Open(DBPath, CFile::modeRead | CFile::typeBinary, NULL);
	//判断是否有可用的索引
	struct_where result;
	if (HasAvilableIndex(where, result)) {
		vector<int>indexPoss;
		string path = "data\\" + db + "\\" + tname + "_" + result.key + ".tid";
		string judge = db + "_" + tname + "_" + result.key;
		indexPoss = indexM.select(path,judge,result);
		if (indexPoss.size() == 0) {
			file.Close();
			info = "Null set !";
			return 0;
		}
		info += "select|";
		for (unsigned int i = 0; i < fields.size(); i++) {
			info += fields[i].key + "  |  ";
		}
		info += "\r\n";
		for (unsigned int i = 0; i < indexPoss.size(); i++) {
			Traversal(file, indexPoss[i], fields, where, info);
		}
	}
	else {
		//没有可用的索引
		info += "select|";
		for (unsigned int i = 0; i < fields.size(); i++) {
			info += fields[i].key + "  |  ";
		}
		info += "\r\n";
		int offset = 0;
		while (file.GetLength()>offset) {
			Traversal(file, offset, fields, where, info);
			offset += lenth;
			file.Seek(offset, file.begin);
		}
	}
	file.Close();
	return 1;
}

